// BluetoothDataReceiver.java
package v2;

import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.interfaces.DBusSigHandler;
import org.freedesktop.dbus.messages.DBusSignal;
import org.freedesktop.dbus.types.Variant;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 蓝牙数据接收器 - 监听移动端蓝牙数据 (dbus-java 3.3.2)
 */
public class BluetoothDataReceiver {
    private DBusConnection connection;
    private List<BluetoothDataListener> listeners = new CopyOnWriteArrayList<>();
    private Map<String, BluetoothDevice> connectedDevices = new ConcurrentHashMap<>();

    public static void main(String[] args) {
        try {
            BluetoothDataReceiver receiver = new BluetoothDataReceiver();
            receiver.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void start() throws DBusException, InterruptedException {
        System.out.println("🚀 启动蓝牙数据接收器...");

        // 建立系统总线连接
        connection = DBusConnection.getConnection(DBusConnection.DEFAULT_SYSTEM_BUS_ADDRESS);

        // 注册信号处理器
        setupSignalHandlers();

        System.out.println("✅ 蓝牙数据接收器启动完成，等待数据...");

        // 保持程序运行
        Thread.currentThread().join();
    }

    private void setupSignalHandlers() throws DBusException {
        // 监听属性变化信号
        connection.addSigHandler(DbusSignals.PropertiesChanged.class, new PropertiesChangedHandler());

        // 监听设备添加信号
        connection.addSigHandler(DbusSignals.InterfacesAdded.class,  new InterfacesAddedHandler());

        // 监听设备移除信号
        connection.addSigHandler(DbusSignals.InterfacesRemoved.class, new InterfacesRemovedHandler());


        System.out.println("📡 信号处理器注册完成");
    }

    /**
     * PropertiesChanged 信号处理器 - 主要的数据接收通道
     */
    private class PropertiesChangedHandler implements DBusSigHandler<DbusSignals.PropertiesChanged> {
        @Override
        public void handle(DbusSignals.PropertiesChanged signal) {
            String path = signal.getPath();

            // 只处理蓝牙设备相关的信号
            if (isBluetoothDevice(path)) {
                String macAddress = extractMacAddress(path);

                System.out.println("\n=== 📡 收到蓝牙设备数据 ===");
                System.out.println("设备: " + macAddress);
                System.out.println("路径: " + path);
                System.out.println("接口: " + signal.interfaceName);

                // 处理变化的属性
                processChangedProperties(macAddress, signal.changedProperties);

                // 通知监听器
                notifyDataReceived(macAddress, signal.changedProperties);
            }
        }

        private void processChangedProperties(String macAddress, Map<String, Variant<?>> properties) {
            for (Map.Entry<String, Variant<?>> entry : properties.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue().getValue();

                System.out.println("属性 '" + key + "': " + value);

                switch (key) {
                    case "Connected":
                        handleConnectionState(macAddress, (Boolean) value);
                        break;
                    case "ServicesResolved":
                        if ((Boolean) value) {
                            handleServicesResolved(macAddress);
                        }
                        break;
                    case "RSSI":
                        handleRssiUpdate(macAddress, (Short) value);
                        break;
                    case "ManufacturerData":
                    case "ServiceData":
                        handleDeviceData(macAddress, key, value);
                        break;
                    case "Name":
                        handleDeviceName(macAddress, (String) value);
                        break;
                    case "Alias":
                        handleDeviceAlias(macAddress, (String) value);
                        break;
                }
            }
        }

        private void handleConnectionState(String macAddress, boolean connected) {
            if (connected) {
                System.out.println("✅ 设备 " + macAddress + " 已连接");
                connectedDevices.put(macAddress, new BluetoothDevice(macAddress));
            } else {
                System.out.println("❌ 设备 " + macAddress + " 已断开");
                connectedDevices.remove(macAddress);
            }

            // 通知监听器连接状态变化
            notifyConnectionChanged(macAddress, connected);
        }

        private void handleServicesResolved(String macAddress) {
            System.out.println("🔧 设备 " + macAddress + " 服务已解析");
        }

        private void handleRssiUpdate(String macAddress, short rssi) {
            System.out.println("📶 设备 " + macAddress + " 信号强度: " + rssi + " dBm");
        }

        private void handleDeviceData(String macAddress, String dataType, Object data) {
            System.out.println("📨 设备 " + macAddress + " " + dataType + ": " + data);

            // 解析具体的蓝牙数据
            if (data instanceof Map) {
                Map<?, ?> dataMap = (Map<?, ?>) data;
                dataMap.forEach((k, v) -> {
                    System.out.println("  数据键: " + k + ", 值: " + v);
                });
            }
        }

        private void handleDeviceName(String macAddress, String name) {
            System.out.println("🏷️  设备 " + macAddress + " 名称: " + name);
            BluetoothDevice device = connectedDevices.get(macAddress);
            if (device != null) {
                device.setName(name);
            }
        }

        private void handleDeviceAlias(String macAddress, String alias) {
            System.out.println("🔤 设备 " + macAddress + " 别名: " + alias);
        }
    }

    /**
     * 新设备添加处理器
     */
    private class InterfacesAddedHandler implements DBusSigHandler<DbusSignals.InterfacesAdded> {
        @Override
        public void handle(DbusSignals.InterfacesAdded signal) {
            String path = signal.objectPath;
            if (isBluetoothDevice(path)) {
                String macAddress = extractMacAddress(path);
                System.out.println("\n🎉 发现新蓝牙设备: " + macAddress);

                // 通知监听器新设备发现
                notifyNewDeviceDiscovered(macAddress);
            }
        }
    }

    /**
     * 设备移除处理器
     */
    private class InterfacesRemovedHandler implements DBusSigHandler<DbusSignals.InterfacesRemoved> {
        @Override
        public void handle(DbusSignals.InterfacesRemoved signal) {
            String path = signal.objectPath;
            if (isBluetoothDevice(path)) {
                String macAddress = extractMacAddress(path);
                System.out.println("\n🗑️  蓝牙设备移除: " + macAddress);
                connectedDevices.remove(macAddress);
            }
        }
    }

    /**
     * 所有信号处理器（调试用）
     */
    private class AllSignalsHandler implements DBusSigHandler<DBusSignal> {
        @Override
        public void handle(DBusSignal signal) {
            // 只显示非 PropertiesChanged 和 非 CustomTest 的信号（避免重复）
            System.out.println("\n🔍 [调试] 收到其他信号:");
            System.out.println("  类型: " + signal.getClass().getSimpleName());
            System.out.println("  路径: " + signal.getPath());
            System.out.println("  内容: " + signal.toString());
        }
    }

    // ==================== 工具方法 ====================

    private boolean isBluetoothDevice(String path) {
        return path != null && path.startsWith("/org/bluez/hci") && path.contains("/dev_");
    }

    private String extractMacAddress(String path) {
        if (path == null) return "unknown";
        try {
            return path.substring(path.lastIndexOf("dev_") + 4)
                    .replace("_", ":")
                    .toUpperCase();
        } catch (Exception e) {
            return "invalid";
        }
    }

    private void notifyDataReceived(String macAddress, Map<String, Variant<?>> data) {
        for (BluetoothDataListener listener : listeners) {
            try {
                listener.onBluetoothDataReceived(macAddress, data);
            } catch (Exception e) {
                System.err.println("通知监听器失败: " + e.getMessage());
            }
        }
    }

    private void notifyConnectionChanged(String macAddress, boolean connected) {
        for (BluetoothDataListener listener : listeners) {
            try {
                listener.onDeviceConnectionChanged(macAddress, connected);
            } catch (Exception e) {
                System.err.println("通知连接状态变化失败: " + e.getMessage());
            }
        }
    }

    private void notifyNewDeviceDiscovered(String macAddress) {
        for (BluetoothDataListener listener : listeners) {
            try {
                listener.onNewDeviceDiscovered(macAddress);
            } catch (Exception e) {
                System.err.println("通知新设备发现失败: " + e.getMessage());
            }
        }
    }

    // ==================== 公开方法 ====================

    public void addListener(BluetoothDataListener listener) {
        listeners.add(listener);
    }

    public void removeListener(BluetoothDataListener listener) {
        listeners.remove(listener);
    }

    public Map<String, BluetoothDevice> getConnectedDevices() {
        return new ConcurrentHashMap<>(connectedDevices);
    }

    public void close() {
        if (connection != null) {
            connection.disconnect();
        }
    }
}